package scfg.utils;

import java.util.*;
import java.io.*;

import scfg.output.Display;
import scfg.output.RNAFormattedFile;
import desposito6.utils.CommandLine;

public class MFEAppender {

	public static Process p;
	public static Scanner pin;
	public static BufferedOutputStream pout;
	private static Display output;
	private static boolean skip;

	static {
		output = new Display("MFEAppender");
	}

	public static boolean processFile(File f) {
		if (f == null || !f.exists() || !f.getName().endsWith(".rna"))
			return false;
		try {
			RNAFormattedFile rnaFile = new RNAFormattedFile(f);
			if(skip && rnaFile.get("mfe") != null){
				output.eout("Skipping "+f.getName());
				return false;
			}
			String seq = rnaFile.get("seq");
			if (seq != null) {
				pout.write((seq + "\n").getBytes());
				pout.flush();
				pin.nextLine();
				String mfe = pin.nextLine().replaceAll(
						"\\s+\\(?\\s*-?\\d+\\.\\d+\\)?", "");
				rnaFile.put("mfe", mfe);
				rnaFile.writeToFile(false);
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static void processDir(File base) {
		if (base == null || !base.exists() || !base.isDirectory())
			return;
		System.out.println("Opening " + base.getAbsolutePath());
		File[] files = base.listFiles();
		Stack<File> stk = new Stack<File>();
		int count = 0;
		Long start = System.currentTimeMillis();
		for (File f : files) {
			if (f.isDirectory())
				stk.push(f);
			else if (f.getName().endsWith(".rna"))
				processFile(f);
			CommandLine.DisplayBar(files.length, count++, (System
					.currentTimeMillis()
					- start)/1000);
		}
		CommandLine.DisplayBarFinish();
		while (!stk.isEmpty())
			processDir(stk.pop());
		System.out.println(base.getName() + " finished. (" + count
				+ " files processed)");
	}

	public static String helpMessage() {
		return "\n[scfg.utils.StructureAggregator]\n\t"
				+ "* -h Display help message.\n\t" + "* -s Source folder.\n\t"
				+ "* -v Display verbose output. (Optional)\n"
				+ "* -skip Skip files already containing MFE predictions. (Optional)\n"
				+ "This program requires RNAfold to run. You can download"
				+ "and install from:\n\t"
				+ "http://www.tbi.univie.ac.at/~ivo/RNA/\n\n";
	}

	/**
	 * <pre>
	 * -h Display help message.
	 * -s Source Directory.
	 * -v Display verbose output.
	 * </pre>
	 * 
	 * -s /home/david/Documents/REU/RNA/rna_files/ -v
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		if (CommandLine.containsArg(args, "-h") >= 0) {
			output.out(helpMessage());
			output.finalizeDisplay();
			return;
		}
		int temp = CommandLine.containsArg(args, "-o");
		if (temp >= 0 && temp < args.length - 1) {
			output = new Display(args[temp + 1], args[temp + 1] + "_error.log",
					true);
		}
		temp = CommandLine.containsArg(args, "-s");
		String sourceName = null;
		if (temp >= 0 && temp < args.length - 1) {
			sourceName = args[temp + 1];
		}
		output.setVerbose(CommandLine.containsArg(args, "-v") >= 0);
		skip = CommandLine.containsArg(args, "-skip") >= 0;
		File srcFile = new File(sourceName);
		try {
			p = Runtime.getRuntime().exec(
					new String[] { "/bin/sh", "-c", "RNAfold" });
			pout = new BufferedOutputStream(p.getOutputStream());
			pin = new Scanner(p.getInputStream());
			processDir(srcFile);
			pin.close();
			pout.write("@\n".getBytes());
		} catch (Exception e) {
			e.printStackTrace();
		}
		output.out("\n\n\n\t[EXITING StructureAggregator.main]");
		output.finalizeDisplay();
	}

}
